/**
 * 给定一个已按照 非递减顺序排列  的整数数组 numbers ，请你从数组中找出两个数满足相加之和等于目标数 target 。

函数应该以长度为 2 的整数数组的形式返回这两个数的下标值。numbers 的下标 从 1 开始计数 ，所以答案数组应当满足 1 <= answer[0] < answer[1] <= numbers.length 。

你可以假设每个输入 只对应唯一的答案 ，而且你 不可以 重复使用相同的元素。

示例 1：

输入：numbers = [2,7,11,15], target = 9
输出：[1,2]
解释：2 与 7 之和等于目标数 9 。因此 index1 = 1, index2 = 2 。
示例 2：

输入：numbers = [2,3,4], target = 6
输出：[1,3]
示例 3：

输入：numbers = [-1,0], target = -1
输出：[1,2]

提示：

2 <= numbers.length <= 3 * 104
-1000 <= numbers[i] <= 1000
numbers 按 非递减顺序 排列
-1000 <= target <= 1000
仅存在一个有效答案
 */

/**
 * 解法1
 * @description 设定头尾两个指针，按行进行遍历，每次循环遍历列，直到找到对应的数的位置，返回[left + 1, right + 1]
 * @param numbers
 * @param target
 * @returns
 */
function eachTwoSum(numbers: number[], target: number): number[] {
    // 数组只有一个数，无解
    if (numbers.length < 2) return [];
    // 从左进行遍历
    for (let left = 0; left < numbers.length; left++) {
        // 设定当前尾指针
        let right = numbers.length - 1;
        // 设置目标数，即目标数 = target - numbers[left];
        const targetNum = target - numbers[left];
        // 左移尾指针查找目标数
        while (right > left && numbers[right] !== targetNum) {
            right--;
        }
        // 尾指针大于当前位置，表示已找到，返回[left + 1, right + 1]
        if (right > left) {
            return [left + 1, right + 1];
        }
    }
    // 未找到，返回空数组
    return [];
}

/**
 * 解法2
 * 头尾之和小于target，头太小，要加(left++)
 * 头尾之和大于target，尾太大，要减(right--)
 * @description 设定头尾两个指针，当头尾之和小于target，表示头指针的数与任何尾指针的数之和均小于target(尾指针是最大的数，再左移尾指针仍然会小于target)，所以需要头指针右移(++);
 * 当头尾之和大于target，表示尾指针的数与任何数相加均会大于target(头指针是最大小的数，再右移头指针仍然会大于target)，所以需要尾指针左移(--)
 * @param numbers
 * @param target
 * @returns
 */
function twoSum(numbers: number[], target: number): number[] {
    if (numbers.length < 2) return [];
    let left = 0;
    let right = numbers.length - 1;
    while (left < right) {
        if (numbers[left] + numbers[right] < target) {
            left++;
        } else if (numbers[left] + numbers[right] > target) {
            right--;
        } else {
            return [left + 1, right + 1];
        }
    }
    return [];
}

export { twoSum };
